/*
 * UserNet  --  TCP/IP implementation in userspace
 * Copyright (C) 2010  Alex Diban
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include "unet/misc.h"
#include "unet/routes.h"


int count = 0;
struct list_head list_routes = { .next = &list_routes, .prev = &list_routes };

struct unet_route *
list_head_to_route (struct list_head *l)
{
  return list_entry(l, struct unet_route, element);
}

int 
unet_route_add(struct unet_route *route){    

  debug_printf("Routes","Request to add:\n");
  debug_printf("Routes","%s ",inet_ntoa(route->Destination));
  debug_printf("Routes","%s ",inet_ntoa(route->Genmask));
  debug_printf("Routes","%s ",inet_ntoa(route->Gateway));
  debug_printf("Routes","unet%d\n",route->id_interface);
  
  route->interface=unet_device_find(route->id_interface);  
  
  if (route->interface!=NULL){	  
    list_add(&route->element, &list_routes);  
    count++;
    return 0;
  }
  else return -1;
}

int unet_count_routes(){
  return count;
}

int unet_route_del(struct unet_route *route){
  
  struct list_head * iterador;
  
  debug_printf("Routes","unet_route_del\n");  
  
  list_for_each(iterador,&list_routes)
  {    
    if (list_head_to_route(iterador)->Destination.s_addr == route->Destination.s_addr && 
      list_head_to_route(iterador)->Genmask.s_addr == route->Genmask.s_addr)
    {
      list_del(iterador);
      count--;
      return 1;
    }    
  }
  //0 si borrado, -1 si no encontrado
  return -1;
}

struct unet_route *unet_get_route(uint32_t id){
   
   int i=0;
   struct list_head * iterador;   
   list_for_each(iterador,&list_routes)
   {
    
    if (i==id)      
	return list_head_to_route(iterador);      
   }
  return NULL;
}

struct unet_device *unet_route_find(struct in_addr Destination){
  
   struct list_head * iterador;
   list_for_each(iterador,&list_routes)
   {
    if ((list_head_to_route(iterador))->Destination.s_addr == (Destination.s_addr & list_head_to_route(iterador)->Genmask.s_addr))
      {
	return list_head_to_route(iterador)->interface;
      }
   }

  return NULL;
}
